#include <stdlib.h>
#include <stdio.h>
#include <spu_mfcio.h>
#include "../ubicus.h"
#include <mc_rand.h>
#include <simdmath.h>
#include "./recu.h"
#include <spu_timer.h>
#include <string.h>
#include <math.h>
#include <libsync.h>//mutex

//instrumenter le code
//#define TEST_AFFECTATION
//#define TEST_RECURRENCE
//#define TEST_DIVERGENCE
//#define TEST_CYCLES
//#define TEST_POINTPARAMETRIQUE
//#define TEST_CHAOS
//#define TEST_MATRICE_POINT_A_B
//#define TEST_FICHIER
//#define TEST_VITESSE

/* allocating the control_block structure on the stack.  We align
 * it by 128 */
control_block_t control_block __attribute__ ((aligned (128)));

typedef union
        {
                PRECISION nombre;
                char t[sizeof(PRECISION)];
        } union_float;
void transitoire(vector PRECISION *vec_float_x, vector PRECISION *vec_float_y, vector PRECISION vec_a, vector PRECISION vec_b);

vector ENTIER testDivergence(vector PRECISION vec_float_x, vector PRECISION vec_x_min, vector PRECISION vec_x_max,
                                                 vector PRECISION vec_float_y, vector PRECISION vec_y_min, vector PRECISION vec_y_max,
                                                         int * diverge);

vector ENTIER testCycles(vector PRECISION vec_float_x , vector PRECISION vec_float_y,
                                                 vector PRECISION vec_a, vector PRECISION vec_b, vector ENTIER vec_couleur);

void enregistrerStructure(vector PRECISION pvec_float_x, vector PRECISION pvec_float_y,
                                                  vector PRECISION pvec_a, vector PRECISION pvec_b,vector ENTIER pvec_couleur,point_parametrique * point);

void ecrireDansFichier(balayage_a_b balayage, FILE * fichier);
PRECISION conversion_float(PRECISION entree);


/*procedure d affichagee du vecteur x */
void pvecf4(vector PRECISION x);



/*procedure d'affichage de la couleur pour la recurrence courante */

void pveci4(vector ENTIER x);
mutex_ea_t mutex;



int main(unsigned long long speid __attribute__ ((unused)),
         unsigned long long argp,
         unsigned long long envp __attribute__ ((unused)))
{

  char enteteBloc, ordretmp;
  unsigned int tag, idA, nbB, itB;
  int  i, j, k ,itA ;
  PRECISION a_min, a_max, b_min, b_max;
  PRECISION a, b, xtmp, ytmp;

  //importation des valeur de ubicus.h
#ifdef ENFLOAT
  vector PRECISION vec_x_min = {x_satu_min, x_satu_min, x_satu_min, x_satu_min};
  vector PRECISION vec_x_max = {x_satu_max, x_satu_max, x_satu_max, x_satu_max};
  vector PRECISION vec_y_min = {y_satu_min, y_satu_min, y_satu_min, y_satu_min};
  vector PRECISION vec_y_max = {y_satu_max, y_satu_max, y_satu_max, y_satu_max};
  vector PRECISION vec_xmin = {x_min, x_min, x_min, x_min};
  vector PRECISION vec_ymin = {y_min, y_min, y_min, y_min};
  vector PRECISION vec_ecart_x = {x_max-x_min, x_max-x_min, x_max-x_min, x_max-x_min};
  vector PRECISION vec_ecart_y = {y_max-y_min, y_max-y_min, y_max-y_min, y_max-y_min};  



#else
  vector PRECISION vec_x_min = {x_satu_min, x_satu_min};
  vector PRECISION vec_x_max = {x_satu_max, x_satu_max};
  vector PRECISION vec_y_min = {y_satu_min, y_satu_min};
  vector PRECISION vec_y_max = {y_satu_max, y_satu_max};
  vector PRECISION vec_xmin = {x_min, x_min};
  vector PRECISION vec_ymin = {y_min, y_min};
  vector PRECISION vec_ecart_x = {x_max-x_min, x_max-x_min};
  vector PRECISION vec_ecart_y = {y_max-y_min, y_max-y_min};  

 


#endif
  // variables pour la detection de cycles



  vector ENTIER vec_couleur;            


  // variables d'enregistrement des resultats
  vector PRECISION vec_float_x, vec_dep_x;
  vector PRECISION vec_float_y, vec_dep_y;

  // variables de test
 
  // variables d'iteration de a et b

  vector PRECISION vec_a;
  vector PRECISION vec_b;

  // point parametrique a retourner
  point_parametrique point;
  balayage_a_b balayage;
 
  //variable d'enregistrement dans un fichier
  FILE *fichier = NULL;
  char nomFichier[15], id[13];
  int erreur = 0;


#ifdef TEST_VITESSE  
        //  initialisation du temps
  void *my_prof_handler = NULL;
  int idT;
  uint64_t debut, tempsExecRecu, tempsExecFic;
  spu_slih_register(MFC_DECREMENTER_EVENT, spu_clock_slih);
  idT = spu_timer_alloc (10, my_prof_handler);
  spu_clock_start();
  spu_timer_start(idT);
#endif
  // First, we reserve a MFC tag for use
  tag = mfc_tag_reserve();
  if (tag == MFC_TAG_INVALID)
  {
    printf ("SPU ERROR, unable to reserve tag\n");
    return 1;
  }

   // DMA the control block information from system memory
 
    mfc_get (&control_block, argp, sizeof (control_block_t), tag, 0, 0);

        //    wait for the DMA to complete
    mfc_write_tag_mask (1 << tag);
    mfc_read_tag_status_all ();
   
        // fin de récupération des données connaitre le processeur unixdu control_block    
    idA = control_block.idA;
    a_min = control_block.a_min;
    a_max = a_min + INTERVALLE_A;
    b_min = control_block.b_min;
    b_max = b_min + MAX*PAS_B;

    mutex = control_block.addr;
    // création des vecteurs contenant des conditions initiales
        balayage.nombre_de_a = 0;
        balayage.nombre_de_b = 0;

    mc_rand_ks_init(1234);
        /*mutex_lock(mutex);
        printf("blocage du mutex\n");
    if (mutex_trylock(mutex))
    {
        printf("erreur mutex");
        return(-1);
    }*/
   // printf("### %u ### Debut du traitement\n", idA );
#ifdef TEST_VITESSE    
	debut = spu_clock_read();    
#endif  

        if (b_max > B_MAX)
        {
                nbB = (int) (((B_MAX-b_min)/PAS_B)+1);
        }
        else
        {
                nbB = NB_B;
        }
       
     //   printf("PAS A : %f PAS_B : %f\n", PAS_A, PAS_B);
    // Début du traitement d'un point (a,b)
     a = a_min;
        for(itA = 0; itA <NB_A; itA++)
    {
#ifdef ENFLOAT
        vec_a = spu_splats(a);
#else
                vec_a = spu_insert(a, vec_a, 0);
                vec_a = spu_insert(a, vec_a, 1);
#endif
		//pvecf4(vec_a);
                //trace de la valeur du vecteur a courant
             // printf("### %u ###\n", idA);
               // pvecf4(vec_a);
                balayage.nombre_de_b = 0;
                b = b_min;
        for (itB = 0; itB < nbB; itB++)
        {
                     //printf("%i/%i, %i/%i\n", itA+1, NB_A, itB+1, NB_B);
                       // printf("                ###\n");
                        //printf("%f %f\n", a, b);
                // On initialise la structure

                point.ca_diverge = 0;
                        point.y_a_du_chaos = 0;
                        point.nombre_singus = 0;
                        enteteBloc = 0x00;
                // On tire 20 conditions initiales
#ifdef ENFLOAT
                vec_b = spu_splats(b);
#else
                        vec_b = spu_insert(b, vec_b, 0);
                        vec_b = spu_insert(b, vec_b, 1);
#endif
               
                        //trace de la valeur du vecteur B courant
                        //printf("### %u ###            vec_b : ", idA);
                      //  pvecf4(vec_b);
                        //fin trace
       
               
             //  printf("coucou\n");
            // Conditions initiales entre xmin et xmax ou ymin et ymax
                for (j = 0; j < NbVecsInit; j++)
            {
                        /*printf("test lol : %i\n", NbVecsInit);
                                test++;*/
       
                               
#ifdef ENFLOAT
                        vec_float_x = mc_rand_ks_0_to_1_f4();
                        vec_float_y = mc_rand_ks_0_to_1_f4();  
#else  
                        vec_float_x = mc_rand_ks_0_to_1_d2();
                        vec_float_y = mc_rand_ks_0_to_1_d2();
#endif                          
                        vec_float_x = spu_mul(vec_float_x, vec_ecart_x);
                        vec_float_y = spu_mul(vec_float_y, vec_ecart_y);
                    vec_float_x = spu_add(vec_float_x, vec_xmin);
                vec_float_y = spu_add(vec_float_y, vec_ymin);


#ifdef TEST_RECURRENCE
                vec_dep_x = vec_float_x;
                    vec_dep_y = vec_float_y;
                        printf("Appel de la recurrence:\n");

#endif
#ifdef TEST_AFFECTATION
            printf("Affectation conditions initiales aleatoires\n");

                                printf("vex_x :");
                pvecf4(vec_float_x);
                    printf("vec_y :");
                    pvecf4(vec_float_y);
#endif
           
           
                    // On fait tourner la récurrence
                                transitoire(&(vec_float_x), &(vec_float_y), vec_a, vec_b);
                               
             
#ifdef TEST_RECURRENCE
                                printf("\n");
                                printf("vecteur x de depart :");
                    pvecf4(vec_dep_x);
                    printf("vecteur y de depart :");
                    pvecf4(vec_dep_y);
#endif
                                // On vire les divergences
                                // ( x>xman ou x<xmin ) ou ( y>ymax ou y<ymin )
                                vec_couleur = testDivergence(vec_float_x, vec_x_min, vec_x_max, vec_float_y, vec_y_min, vec_y_max, &(point.ca_diverge));
                                // On charge les vecteurs de départ
                                vec_couleur = testCycles(vec_float_x ,vec_float_y, vec_a, vec_b, vec_couleur);
                               
                                //recherche de chaos

                                 enregistrerStructure(vec_float_x,  vec_float_y, vec_a,vec_b, vec_couleur,&point);
                                // enregistrement dans la structure
								//if (point.nombre_singus >0){
							//	printf("nombre singus : %i\n",point.nombre_singus);}
                        }//fin nbvecsinit
                        balayage.tableau_points[balayage.nombre_de_a][balayage.nombre_de_b] = point;
                        balayage.nombre_de_b ++;
                        b += PAS_B;
                }// fin parcours b
                balayage.nombre_de_a ++;
                a += PAS_A;
    }// fin parcours a
   
#ifdef TEST_VITESSE
tempsExecRecu = (spu_clock_read() - debut);
debut = spu_clock_read();    
#endif
#ifdef TEST_MATRICE_POINT_A_B



printf("BALAYAGE :\n nombre de a : %i\n nombre de b : %i\n",
balayage.nombre_de_a, balayage.nombre_de_b);
        for(i=0; i<balayage.nombre_de_a; i++)
        {
                for(j=0; j<balayage.nombre_de_b; j++)
                {
                        printf("  A[%i]B[%i] :", i, j);
                        printf(" nombre singus :%i\n", balayage.tableau_points[i][j].nombre_singus);
                        for(k=0; k < balayage.tableau_points[i][j].nombre_singus ; k++)
                        {

                                printf("        - o=%i x=%f y=%f\n", balayage.tableau_points[i][j].ordre[k],
                                balayage.tableau_points[i][j].x_point_min[k],balayage.tableau_points[i][j].y_point_min[k]);
                        }
                }
        }    
#endif
   
   // mutex_lock(mutex);
//      printf("blocage du mutex\n");
    //if (mutex_trylock(mutex))
   // {
   //   printf("erreur mutex");
   //   return(-1);
   // }PRECISION conversion_float(PRECISION entree)

        sprintf(id, "%i", idA);
        strcpy(nomFichier, "./resultat/");
        strcat(nomFichier, id);
        //printf("%s\n", nomFichier);
        fichier = fopen(nomFichier, "wb");
        //trace = fopen("trace", "a");
        if (fichier != NULL)
        {
#ifdef TEST_FICHIER
                printf("ouverture du fichier resultat ...\necriture de la structure dans le fichier\n");
#endif

ecrireDansFichier(balayage, fichier);
       
        }
        else
        {
                printf("erreur d'ouverture du fichier");
                return(3);
        }
#ifdef TEST_FICHIER
       
        printf("fermeture du fichier resultat ...\n");
#endif
        erreur = fclose(fichier);
        if (erreur != 0)
        {
                printf("erreur de fermeture du fichier\n");
                return(3);
        }

    //printf("deblocage du mutex\n");
   // mutex_unlock(mutex);
#ifdef TEST_VITESSE
        tempsExecFic = (spu_clock_read() - debut);

        spu_clock_stop();
        printf("temps d'execution de la recurrence : %llu \n temps d'enregistrement dans le fichier : %llu \n", tempsExecRecu, tempsExecFic);
#endif
        return (0);
}
//FIN DU MAIN


void pvecf4(vector PRECISION x)
{
#ifdef ENFLOAT
        printf("{%f, %f, %f, %f}\n", spu_extract(x, 0), spu_extract(x, 1), spu_extract(x, 2), spu_extract(x, 3));
#else
        printf("{%lf, %lf}\n", spu_extract(x, 0), spu_extract(x, 1));
#endif  
}

void pveci4(vector ENTIER x)
{
#ifdef ENFLOAT
        printf("{%d, %d, %d, %d}\n", spu_extract(x, 0), spu_extract(x, 1), spu_extract(x, 2), spu_extract(x, 3));
#else
        printf("{%llu, %llu}\n", spu_extract(x, 0), spu_extract(x, 1));
#endif
}

PRECISION conversion_float(PRECISION entree)
{
        union_float is, os ;
       
        is.nombre = entree;
#ifdef ENFLOAT
        os.t[0]=is.t[3];
        os.t[1]=is.t[2];
        os.t[2]=is.t[1];
        os.t[3]=is.t[0];
#else
        os.t[0]=is.t[7];
        os.t[1]=is.t[6];
        os.t[2]=is.t[5];
        os.t[3]=is.t[4];
        os.t[4]=is.t[3];
        os.t[5]=is.t[2];
        os.t[6]=is.t[1];
        os.t[7]=is.t[0];
#endif
        //printf("                       %f, %f\n",is.nombre,os.nombre);
        return (os.nombre);
}

void transitoire(vector PRECISION *vec_float_x, vector PRECISION *vec_float_y, vector PRECISION vec_a, vector PRECISION vec_b)
{
        int i;
        for (i = 0; i < NbItTransit; i++)
        {
               recu((vec_float_x),(vec_float_y), vec_a,  vec_b);      
#ifdef TEST_RECURRENCE  
               printf("\nIteration %i : \n     x = ", i+1);
               pvecf4(*vec_float_x);
               printf("        y = ");
               pvecf4(*vec_float_y);
#endif
        }      
}


vector ENTIER testDivergence(vector PRECISION vec_float_x, vector PRECISION vec_x_min, vector PRECISION vec_x_max,
                             vector PRECISION vec_float_y, vector PRECISION vec_y_min, vector PRECISION vec_y_max,
                             int * diverge)
{
        vector ENTIER vec_couleur;
#ifdef ENFLOAT
        vector ENTIER vec_zero = {0,0,0,0};
        vec_couleur = spu_or(
                                 spu_or(
                                         spu_or(
                                                 spu_or(isgreaterf4(vec_float_x, vec_x_max), islessf4(vec_float_x, vec_x_min))
                                         ,spu_or(isgreaterf4(vec_float_y, vec_y_max), islessf4(vec_float_y, vec_y_min)))
                                 , spu_or(isnanf4(vec_float_x), isnanf4(vec_float_y)))
                           , spu_or(isinff4(vec_float_x), isinff4(vec_float_y)));

#else
        vector ENTIER vec_zero = {0,0};
        vec_couleur = spu_or(
                                 spu_or(
                                         spu_or(
                                                 spu_or(isgreaterd2(vec_float_x, vec_x_max), islessd2(vec_float_x, vec_x_min))
                                         ,spu_or(isgreaterd2(vec_float_y, vec_y_max), islessd2(vec_float_y, vec_y_min)))
                                 , spu_or(isnand2(vec_float_x), isnand2(vec_float_y)))
                           , spu_or(isinfd2(vec_float_x), isinfd2(vec_float_y)));
#endif
        *diverge = *diverge || !(vec_couleur == vec_zero);
#ifdef TEST_DIVERGENCE
#ifdef ENFLOAT
                                printf("TEST DES DIVERGENCES :\n");            
                                printf("        >xmax?");
                        printf("                ");
       
                                pveci4(isgreaterf4(vec_float_x, vec_x_max));
                                pveci4(isnanf4(vec_float_x));
                                printf("        <xmin?");
                        printf("                ");
                                pveci4(islessf4(vec_float_x, vec_x_min));                              
                                printf("        >ymax?");
                        printf("                ");
                                pveci4(isgreaterf4(vec_float_y, vec_y_max));
                                printf("        <xmin?");
                        printf("                ");
                                pveci4(islessf4(vec_float_y, vec_y_min));                              
                                printf("        x diverge ?             ");
                                pveci4(spu_or(isgreaterf4(vec_float_x, vec_x_max),islessf4(vec_float_x, vec_x_min)));
                                printf("        y diverge ?             ");
                                pveci4(spu_or(isgreaterf4(vec_float_y, vec_y_max), islessf4(vec_float_y, vec_y_min)));
                                printf("        divergencvec_couleur = spu_or(
                                        spu_or(
                                                spu_or(
                                                        spu_or(isgreaterd2(vec_float_x, vec_x_max), islessd2(vec_float_x, vec_x_min))
                                                ,spu_or(isgreaterd2(vec_float_y, vec_y_max), islessd2(vec_float_y, vec_y_min)))
                                        , spu_or(isnand2(vec_float_x), isnand2(vec_float_y)))
                                  , spu_or(isinfd2(vec_float_x), isinfd2(vec_float_y)));es detectee : %i\n", diverge);
                        printf("                ");
                        pveci4(vec_couleur);
                                printf("\n\n    detection des divergences\n");
                                if (diverge == 1)
                                {
                                        printf("                ca diverge !!! \n");
                                }
                                else
                                {
                                        printf("                ca ne diverge pas !!! \n");
                                }
        #else
                                printf("TEST DES DIVERGENCES :\n");            
                                printf("        >xmax?");
                        printf("                ");
                                pvecf4(vec_float_x);
                                pvecf4(vec_x_max);
                                pveci4(isgreaterd2(vec_float_x, vec_x_max));
                                pveci4(isnand2(vec_float_x));
                                printf("        <xmin?");
                        printf("                ");
                                pveci4(islessd2(vec_float_x, vec_x_min));                              
                                printf("        >ymax?");
                        printf("                ");
                                pveci4(isgreaterd2(vec_float_y, vec_y_max));
                                printf("        <xmin?");
                        printf("                ");
                                pveci4(islessd2(vec_float_y, vec_y_min));                              
                                printf("        x diverge ?             ");
                                pveci4(spu_or(isgreaterd2(vec_float_x, vec_x_max),islessd2(vec_float_x, vec_x_min)));
                                printf("        y diverge ?             ");
                                pveci4(spu_or(isgreaterd2(vec_float_y, vec_y_max), islessd2(vec_float_y, vec_y_min)));
                                printf("        divergences detectee : %i\n", *diverge);
                        printf("                ");
                        pveci4(vec_couleur);
                                printf("\n\n    detection des divergences\n");
                                if (*diverge == 1)
                                {
                                        printf("                ca diverge !!! \n");
                                }
                                else
                                {
                                        printf("                ca ne diverge pas !!! \n");
                                }
        #endif                  
                               
#endif                  
        return(vec_couleur);
}

vector ENTIER testCycles(vector PRECISION pvec_float_x , vector PRECISION pvec_float_y, vector PRECISION vec_a, vector PRECISION vec_b, vector ENTIER pvec_couleur)
{
#ifdef ENFLOAT
        vector PRECISION vec_epsilon_x = {EpsilonX, EpsilonX, EpsilonX, EpsilonX};
        vector PRECISION vec_epsilon_y = {EpsilonY, EpsilonY, EpsilonY, EpsilonY};
        vector ENTIER vec_zero = {0,0,0,0};
#else
        vector PRECISION vec_epsilon_x = {EpsilonX, EpsilonX};
	    vector PRECISION vec_epsilon_y = {EpsilonY, EpsilonY};
        vector ENTIER vec_zero = {0,0};
#endif
       
        ENTIER it;
        vector ENTIER vec_couleur,vec_it, temp_recherche_cycle_x_i4, temp_recherche_cycle_y_i4, cycle_trouve;
        vector PRECISION vec_dep_x, vec_dep_y, vec_float_x, vec_float_y;
        vec_couleur = pvec_couleur;
       
        vec_float_x = pvec_float_x;
        vec_float_y = pvec_float_y;
        vec_dep_x = vec_float_x;
        vec_dep_y = vec_float_y;
#ifdef TEST_CYCLES
        printf("TEST DES CYCLES : \n");
        printf("vecteur de depart : \n");
        printf("                ");
        pvecf4(vec_dep_x);
        printf("                ");
        pvecf4(vec_dep_y);
#endif
        for(it=1; it < OrdreMaxCycle; it++)
        {
#ifdef ENFLOAT
                vec_it = spu_splats(it);
#else
                vec_it = spu_insert(it, vec_it, 0);
                vec_it = spu_insert(it, vec_it, 1);
#endif
                //  On fait tourner une récurrence
                recu(&(vec_float_x),&(vec_float_y), vec_a,  vec_b);    
                // on verifie si la recurrence courante est égale au vecteur de depart : |x - depart|< Epsylon  ET |y - depart| < Epsylon
#ifdef ENFLOAT
                temp_recherche_cycle_x_i4 = islessf4( fabsf4( spu_sub(vec_float_x, vec_dep_x) ), vec_epsilon_x);
                temp_recherche_cycle_y_i4 = islessf4( fabsf4( spu_sub(vec_float_y, vec_dep_y) ), vec_epsilon_y);
                cycle_trouve = spu_and( spu_and( temp_recherche_cycle_x_i4, temp_recherche_cycle_y_i4 ), spu_cmpeq( vec_couleur, vec_zero ) );
#else
                temp_recherche_cycle_x_i4 = islessd2( fabsd2( spu_sub(vec_float_x, vec_dep_x) ), vec_epsilon_x);
                temp_recherche_cycle_y_i4 = islessd2( fabsd2( spu_sub(vec_float_y, vec_dep_y) ), vec_epsilon_y);
                cycle_trouve = spu_and( spu_and( temp_recherche_cycle_x_i4, temp_recherche_cycle_y_i4 ), isequald2((vector double)vec_couleur, (vector double)vec_zero ) );
#endif
                                       
                                       
                // si il a decouverte d'un cycle alors ecrire l'ordre du cycle dans vex_couleur
                vec_couleur = spu_sel(vec_couleur, vec_it, cycle_trouve);
#ifdef TEST_CYCLES
                printf("resultat similaire aux valeurs de depart ?\n");
                printf("cycle trouve ?: ");
                pveci4(cycle_trouve);
                printf("vecteur x : ");
                pvecf4(vec_float_x);
                printf("vecteur y : ");
                pvecf4(vec_float_y);
                printf("cycles : ");
                pveci4(vec_couleur);
#endif          

        }//fin recherche cycle
        return (vec_couleur);
}

void enregistrerStructure(vector PRECISION pvec_float_x, vector PRECISION pvec_float_y, vector PRECISION pvec_a, vector PRECISION pvec_b,vector ENTIER pvec_couleur,point_parametrique * point)
{



  // variables pour la detection de cycles



  vector ENTIER vec_couleur;            

 
  // variables d'enregistrement des resultats
  vector PRECISION vec_float_x;
  vector PRECISION vec_float_y;
  vector PRECISION vec_float_test_xmin;
  vector PRECISION vec_float_test_ymin;
  // variables de test
  // variables d'iteration de a et b
  vector PRECISION vec_a;
  vector PRECISION vec_b;
  int  i, k, couleur, dejaTrouve;
  PRECISION  xmin, ymin, xtmp;
vec_a = pvec_a;
vec_b = pvec_b;
vec_float_x = pvec_float_x;
vec_float_y = pvec_float_y;
vec_couleur = pvec_couleur;
i=0;
#ifdef ENFLOAT
                                while( i<4 && (point->nombre_singus)<nombre_max_singus )
#else
                                while( i<2 && (point->nombre_singus)<nombre_max_singus )
#endif
                                {
                                        //recuperation du x le plus faibles dans les point fixes existants //extraction des valeur du vecteur courant
                                        xmin = spu_extract(vec_float_x, i);
                                        ymin = spu_extract(vec_float_y, i);
                                        couleur = spu_extract(vec_couleur, i);
#ifdef TEST_POINTPARAMETRIQUE
                                        printf("enregistrement de x et y dans la structure\n");
                                        printf("extraction de l'element %i\n :", i);
                                        printf("  x = %f\n  y = %f\ncouleur = %i\n", xmin, ymin, couleur);
#endif

                                        if ( couleur > 0)
                                        {
                                                //test du x plus petit
                                                vec_float_test_xmin = spu_splats(xmin);
                                                vec_float_test_ymin = spu_splats(ymin);
                                                for( k=0 ; k < couleur ; k++)
                                                {
                                                        recu(&vec_float_test_xmin, &vec_float_test_xmin, vec_a, vec_b );
                                                        xtmp = spu_extract(vec_float_test_xmin, 0);
#ifdef TEST_POINTPARAMETRIQUE                                                  
                                                        printf("%f ?< %f\n", xtmp, xmin);
#endif
                                                        if ( xtmp < xmin ) //si le x courant est plus petit alors le recuperer
                                                        {
#ifdef TEST_POINTPARAMETRIQUE                                                  
                                                                printf("decouverte d'un nouveau point avec x plus petit\n");
#endif
                                                                xmin = xtmp;
                                                                ymin = spu_extract(vec_float_test_ymin, 0);
                                                        }
#ifdef TEST_POINTPARAMETRIQUE                                                  
                                                        else
                                                        {
                                                                printf("non\n");
                                                        }
#endif
                                                }
                                                // on a recupere le point avec la x plus petit maintenant il faut le comparer a ceux de la structure
                   
                                           
                                                //on recherche si le x a deja été trouvé pour le meme point du me ordre
                                                dejaTrouve = 0;
                                                for (k=0 ;k< point->nombre_singus; k++)
                                                        {
                                                                if((point->ordre[k] == couleur
                                                                && (fabs(point->x_point_min[k] - xmin)< EpsilonX)
                                                                && (fabs(point->y_point_min[k] - ymin)< EpsilonY)) )
                                                                {
                                                                  dejaTrouve=1;
                                                                }
                                                        }
                                                if (! dejaTrouve)
                                                  {
													//printf("trouve singus ! %i\n", point->nombre_singus);
                                                    point->ordre[point->nombre_singus] = couleur;
                                                    point->x_point_min[point->nombre_singus] = xmin;
                                                    point->y_point_min[point->nombre_singus] = ymin;
                                                               
                                                    point->nombre_singus++;                                         
												  }


#ifdef TEST_POINTPARAMETRIQUE                                                  
                                                    printf("enregistrement des valeurs o=%i x=%f y=%f\n"
                                                           , point->ordre[point->nombre_singus]
                                                           , point->x_point_min[point->nombre_singus]
                                                           , point->y_point_min[point->nombre_singus]);
                                                   
#endif
                                        }
                                              

                                        else if (couleur == 0 && point->y_a_du_chaos == 0)
                                        {
                                            point->ordre[point->nombre_singus] = couleur;
                                            point->x_point_min[point->nombre_singus] = xmin;
                                            point->y_point_min[point->nombre_singus] = ymin;
                                            point->nombre_singus ++;
                                            point->y_a_du_chaos = 1;
                                        }
#ifdef TEST_POINTPARAMETRIQUE                                                  

                                        else if (couleur < 0)
                                        {
                                                printf("point divergent\n");
                                        }
#endif
									i++;
                                }
#ifdef TEST_POINTPARAMETRIQUE                                                  
                                printf("                                                                les valeurs du tableau sont\n");
                                for (i=0 ; i < point->nombre_singus; i++)
                                {
                                        printf("                                                                  -[%i]  o=%i x=%f y=%f\n" , i,  point->ordre[i], point->x_point_min[i],
                                        point->y_point_min[i]);
                                }
#endif
}




void ecrireDansFichier(balayage_a_b balayage, FILE * fichier)
{

  char enteteBloc, ordretmp;

  int  i, j, k ;
 
  PRECISION xtmp, ytmp;
        // printf("nombre de point [a][b] : %i\n", balayage.nombre_de_a*balayage.nombre_de_b);
                //fwrite(&(t),sizeof(t),1,fichier);
                for(i=0; i<balayage.nombre_de_a; i++)
                {
                        for(j=0; j<balayage.nombre_de_b; j++)
                        {      
                               
//                              
//                              fprintf(stdout, "\n %i %i %i %i", idA, balayage.tableau_points[i][j].nombre_singus, balayage.tableau_points[i][j].ca_diverge, balayage.tableau_points[i][j].y_a_du_chaos);
                                enteteBloc = (balayage.tableau_points[i][j].y_a_du_chaos<<6 & CHAOS) + (balayage.tableau_points[i][j].ca_diverge<<7 & DIVERGE) + (balayage.tableau_points[i][j].nombre_singus);
        //                      printf("___>    %x = %x %x %x\n", enteteBloc, (enteteBloc&0x3f) , enteteBloc&DIVERGE, enteteBloc&CHAOS);
                                fwrite(&(enteteBloc), sizeof(enteteBloc), 1, fichier);

                                for(k=0; k < balayage.tableau_points[i][j].nombre_singus ; k++)
                                {
                //                      fprintf(stdout, "       %i %f %f", balayage.tableau_points[i][j].ordre[k], balayage.tableau_points[i][j].x_point_min[k], balayage.tableau_points[i][j].y_point_min[k]);
                                        ordretmp = 0|balayage.tableau_points[i][j].ordre[k];
                                        fwrite(&(ordretmp),sizeof(ordretmp),1,fichier);
                                        xtmp = conversion_float(balayage.tableau_points[i][j].x_point_min[k]);
                                        ytmp = conversion_float(balayage.tableau_points[i][j].y_point_min[k]);
                                fwrite(&(xtmp),sizeof(xtmp),1,fichier);
                                fwrite(&(ytmp),sizeof(ytmp),1,fichier);

                                }
                        }
                }  
}
